﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace Enter.DataCommon
{
	public class DataMapDictionary : MapSet
	{
		private object[] _Values;

		private readonly MapSetSchema _Schema;

		public DataMapDictionary(MapSetSchema Schema)
		{
			_Schema = Schema;
			int fieldCount = _Schema.FieldCount;
			this._Values = new object[fieldCount];
		}

		#region Set/Get


		/// <summary>
		/// 设置成员字段的值
		/// </summary>
		/// <param name="field">成员字段名称</param>
		/// <param name="value">成员字段的值</param>
		/// <returns></returns>
		private bool SetValue(string field, object value)
		{
			int index = _Schema.IndexOf(field);
			if (index < 0)
			{
				return false;
			}
			else
			{
				this._Values[index] = value ?? DBNull.Value;
				return true;
			}
		}
		/// <summary>
		/// 设置成员字段的值
		/// </summary>
		/// <param name="index">成员字段编号[_schema.indexOf]方法确定。</param>
		/// <param name="value">成员字段的值</param>
		/// <returns></returns>
		private bool SetValue(int index, object value)
		{
			if (index < 0 || index >= this._Values.Length)
			{
				return false;
			}
			else
			{
				this._Values[index] = value ?? DBNull.Value;
				return true;
			}
		}
		/// <summary>
		/// 获取成员字段的值
		/// </summary>
		/// <param name="index">成员字段编号</param>
		/// <returns></returns>
		private object GetValue(int index)
		{
			if (index < 0)
				return null;
			else
				return this._Values[index];
		}

		/// <summary>
		/// 获取成员字段的值
		/// </summary>
		/// <param name="field">成员字段名称</param>
		/// <returns></returns>
		private object GetValue(string field)
		{
			int index = _Schema.IndexOf(field);
			if (index < 0)
				return null;
			else
				return this._Values[index];
		}
		/// <summary>
		/// 获取成员字段的值
		/// </summary>
		/// <param name="field">成员字段名称</param>
		/// <param name="index">输出成员字段的编号，与[_schema.IndexOf]方法的效果相同。</param>
		/// <returns></returns>
		private object GetValue(string field, out int index)
		{
			index = _Schema.IndexOf(field);
			if (index < 0)
				return null;
			else
				return this._Values[index];
		}

		/// <summary>
		/// 获取或设置成员字段的值
		/// </summary>
		/// <param name="field">成员字段</param>
		/// <returns>当field不存在时返回空。</returns>
		public override object this[string field]
		{
			get
			{
				object val = GetValue(field);
				return val == DBNull.Value ? null : val;
			}
			protected internal set
			{
				SetValue(field, value);
			}
		}

		/// <summary>
		/// 获取或设置成员字段的值
		/// </summary>
		/// <param name="index">成员字段的编号[DataSchema.IndexOf]方法确定</param>
		/// <returns>当index不存在时返回空。</returns>
		public override object this[int index]
		{
			get
			{
				object val = GetValue(index);
				return val == DBNull.Value ? null : val;
			}
			protected internal set
			{
				SetValue(index, value);
			}
		}

		/// <summary>
		/// 获取字段值
		/// </summary>
		/// <typeparam name="T">成员字段的数据类型</typeparam>
		/// <param name="field">成员字段</param>
		/// <returns>字段值</returns>
		protected internal override T Get<T>(string field)
		{
			object val = GetValue(field);
			if (val != null)
			{
				// 如果是空值，则返回T默认值
				if (DBNull.Value.Equals(val))
				{
					return default(T);
				}
				else
				{
					try
					{
						return (T)val;
					}
					catch
					{
						return (T)Convert.ChangeType(val, typeof(T));
					}
				}
			}
			else
			{
				return default(T);
			}
		}

		/// <summary>
		/// 设置字段值
		/// </summary>
		/// <typeparam name="T">成员字段的数据类型</typeparam>
		/// <param name="field">成员字段</param>
		/// <param name="value">成员字段的值</param>
		/// <remarks>返回true表示修改成功</remarks>
		protected internal override bool Set<T>(string field, T value)
		{
			int index;
			object fieldVal = GetValue(field, out index);

			if (fieldVal != null)
			{
				// 一次性装箱，降低多次装箱带来的性能损失。
				object val = value;
				if (DBNull.Value.Equals(val))
				{
					if (DBNull.Value.Equals(fieldVal))
						return false;
					else
						fieldVal = val;
				}
				else
				{
					if (fieldVal.Equals(val))
					{
						return false;//与原始值一致，不需要修改
					}
					else
					{
						fieldVal = val;
					}
				}
			}
			else
			{
				fieldVal = (object)value;
			}
			// 更新成员字段的值
			SetValue(index, fieldVal);
			// 返回true表示更新成功。
			return true;
		}

		#endregion
	}
}
